#include "Langue.h"
#include <map>
#include <vector>
#include <cstring>
#include <string>
#include <iostream>
#include <iterator>

using namespace std;

Langue::Langue(std::string nomLangue){
	this->nomLangue = nomLangue;	
	this->nbMotsTotal = 0; 	// nombre de mots total pour cette langue
	this->nbTrigrammesTotal = 0;	// nombre de trigrammes total pour cette langue
	this->nbMotsTotalCorpus = 0; // nombre de mots total pour cette langue
	this->nbTrigrammesTotalCorpus = 0; // nombre de trigrammes total pour cette langue
	this->probaMotInconnu = 0.0;
	this->probaTrigrammeInconnu = 0.0;
}

Langue::~Langue(){
	//détruire les maps
}
//Fonction qui permet de savoir si la map mot contient ou non le mot
bool Langue::possede_mot(std::string mot){
	return mapMotsOcc[mot];
}
//Fonction qui permet de savoir si la map trigramme contient ou non le trigramme	
bool Langue::possede_trigramme(std::string trigramme){
	return mapTrigrammesOcc[trigramme];		
}
//Permet d'ajouter un mot
void Langue::ajoute_mot(std::string mot){
	string minus = getMinuscule(mot); // Mot tout en minuscules.
	if(possede_mot(minus)){
		incremente_motOcc(minus);
	}
	else{	
		mapMotsOcc[minus] = 1;
		incremente_nbMotsTotal();
	}

}
//Permet d'ajouter un trigramme
void Langue::ajoute_trigramme(std::string trigramme){
	string minus = getMinuscule(trigramme);
	if(possede_trigramme(trigramme)){
		incremente_trigrammeOcc(minus);
	}
	else{	
		mapTrigrammesOcc[minus] = 1;
		incremente_nbTrigrammesTotal();
	}
}
//Permet d'incrementer le compteur de mot 
void Langue::incremente_nbMotsTotal(){
	nbMotsTotal++;
	nbMotsTotalCorpus++;
}
//permet d'incrementer le compteur de trigramme
void Langue::incremente_nbTrigrammesTotal(){
	nbTrigrammesTotal++;
	nbTrigrammesTotalCorpus++;
}
//Incremente le compteur d'occurence de chaque mot
void Langue::incremente_motOcc(std::string mot){
	mapMotsOcc[mot]++;
	nbMotsTotalCorpus++;
}
//Increment le compteur d'occurence de chaque trigramme
void Langue::incremente_trigrammeOcc(std::string trigramme){
	mapTrigrammesOcc[trigramme]++;
	nbTrigrammesTotalCorpus++;
}
//Permet de calculer la probabilité de chaque trigramme
void Langue::calcule_probabilite_trigramme(){
	for(map<string, int>::iterator it=mapTrigrammesOcc.begin(); it!=mapTrigrammesOcc.end(); ++it){
		mapTrigrammesProba[it->first] = (1 + it->second) / (double)(nbTrigrammesTotal + nbTrigrammesTotalCorpus);
	}	
}
//Permet de calculer la probabilité de chaque mot
void Langue::calcule_probabilite_mot(){
	for(map<string, int>::iterator it=mapMotsOcc.begin(); it!=mapMotsOcc.end(); ++it){
		mapMotsProba[it->first] = (1 + it->second) / (double)(nbMotsTotal + nbMotsTotalCorpus);
	}	
}
//Permet de connaitre le nombre de mot d'un langage
int Langue::get_nbMotsTotal(){
	return nbMotsTotal;	
}
//Permet de connaitre le nombre de trigramme d'un langage
int Langue::get_nbTrigrammesTotal(){
	return nbTrigrammesTotal;	
}
//Permet de connaitre la langue d'un mot
std::string Langue::get_nomLangue(){
	return nomLangue;
}	
//Retourne la map des occurences de mot
std::map <std::string, int> Langue::get_mapMotsOcc(){
	return mapMotsOcc;
}
//Retourne la map des occurences de trigramme
std::map <std::string, int> Langue::get_mapTrigrammesOcc(){
	return mapTrigrammesOcc;
}
//Retourne la probabilite d'un trigramme donne en parametre
double Langue::get_proba_trigramme(std::string trigramme){
	return Langue::mapTrigrammesProba[trigramme];
}
//Retourne la probabilite d'un mot donne ne parametre
double Langue::get_proba_mot(std::string mot){
	return Langue::mapMotsProba[mot];	
}


double Langue::get_proba_TrigrammeInconnu(std::string trigramme){
	return probaTrigrammeInconnu;
}

double Langue::get_proba_MotInconnu(std::string mot){
	return probaMotInconnu;
}

// Retourne le mot passé en paramètres, sous forme "lower case".
std::string Langue::getMinuscule(const std::string& mot)
{
	char* c = new char [mot.size()+1];
	strcpy (c, mot.c_str());

	for(unsigned int i = 0; i < mot.length(); i++) {
		c[i] = tolower(c[i]);
	}
	string s = c;
	return s;
}
